package com.webchat.netty.gateway.config;


import com.webchat.common.constants.NettySocketConstants;
import com.webchat.netty.gateway.common.PropertyLoader;
import com.webchat.netty.gateway.handler.NettyGatewayChannelInitializer;
import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.Channel;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelOption;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import io.netty.handler.logging.LogLevel;
import io.netty.handler.logging.LoggingHandler;
import jakarta.annotation.PreDestroy;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.event.ContextClosedEvent;
import org.springframework.context.event.ContextRefreshedEvent;
import org.springframework.context.event.EventListener;

@Slf4j
public class NettyGatewayServer {

    private final EventLoopGroup bossGroup = new NioEventLoopGroup(1);

    private final EventLoopGroup workerGroup = new NioEventLoopGroup(10);

    /**
     * 服务端链接管道
     */
    private Channel serverChannel;

    @EventListener(ContextRefreshedEvent.class)
    public void start() throws InterruptedException {

        int port = PropertyLoader.safeGetProperty("netty.server.port", Integer.class);

        ServerBootstrap bootstrap = new ServerBootstrap();
        bootstrap.group(bossGroup, workerGroup)
                 .channel(NioServerSocketChannel.class)
                 .handler(new LoggingHandler(LogLevel.INFO))
                 .childHandler(new NettyGatewayChannelInitializer());
        ChannelFuture future = bootstrap.bind(port).sync();
        serverChannel = future.channel();
        log.info("Netty gateway Server started on port {}", port);
    }

    @PreDestroy
    @EventListener(ContextClosedEvent.class)
    public void stop() {
        if (serverChannel == null) {
            return;
        }
        serverChannel.close();
        if (!bossGroup.isShutdown()) {
            bossGroup.shutdownGracefully();
        }
        if (!workerGroup.isShutdown()) {
            workerGroup.shutdownGracefully();
        }
    }
}
